package com.example.myapplication

import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.example.myapplication.db.ApplyUser
import com.example.myapplication.db.Repository
import com.example.myapplication.db.Reward
import com.example.myapplication.db.User
import com.example.myapplication.db.UserDatabase
import com.example.myapplication.type.SortOrder
import com.example.myapplication.type.SortType
import com.example.myapplication.utils.DivisionString
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainViewModel(application: Application): AndroidViewModel(application) {
    private val repository = Repository(UserDatabase.getDatabase(application).userDao())
    val userList : LiveData<List<User>> = repository.loadUsers()
    private val thisUserList= MediatorLiveData<List<User>>()
    val Logged_user: MutableLiveData<String> = MutableLiveData()
    private val _loggedInUser = MutableLiveData<String>()
    val thisRewardContext:MutableLiveData<Reward> = MutableLiveData()
    val loggedInUser: LiveData<String> get() = _loggedInUser
    private val json= Gson()
    init {
        thisUserList.addSource(repository.loadUsers()){ users ->
            thisUserList.value = users
            Log.d("MainViewModel", "Users loaded: $users")
        }
        thisUserList.observeForever{
            Log.d("MainViewModel", "Observed userList: $thisUserList")
        }
    }
    fun login(account: String, password: String) {
        val userList=thisUserList.value
        if (userList.isNullOrEmpty()) {
            // Handle empty or null user list
            return
        }

        val user = userList.find { it.account == account && it.password == password }
        if (user != null) {
            _loggedInUser.value = user.account
        } else {
            _loggedInUser.value=""
        }
    }
    fun saveUser(user: User) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.saveUser(user)
            Log.d("MainViewModel", "User saved: ${user.account}")
        }
    }
    fun findUserByAccount(account:String):User?{
        thisUserList.value?.forEach{
            if (account == it.account){
                return it
            }
        }
        return null
    }
    suspend fun fillUserInformation(id:Int, selfIntroduce:String){
        viewModelScope.launch(Dispatchers.IO) {
            repository.updateNewSelfIntroduction(id,selfIntroduce)

        }
    }
    suspend fun fillUserAward(id:Int, award:String){
        repository.updateReward(id,award)
    }
    fun deleteAll() {
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteAll()
            Log.d("MainViewModel", "All users deleted")
        }
    }
    fun updateUser(user: User) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.updateUser(user)
            Log.d("MainViewModel", "User updated: ${user.account}")
        }
    }
    /**
     * 先判断时间和价格，在判断顺序，再判断是否解决
     */
    fun getAllRewardByTimeOrPrice(sortRewordType: SortType,orderType:SortOrder):List<Reward>{
        val allRecipe=initialReward()
        when(sortRewordType){
            SortType.ByPrice ->{
                if (orderType==SortOrder.Order)
                {
                    allRecipe.sortBy {
                        it.price
                    }
                }else{
                    allRecipe.sortByDescending  {
                        it.price
                    }
                }
            }
            SortType.ByTime ->{
                if (orderType==SortOrder.Order)
                {
                    allRecipe.sortBy {
                        it.time.toLong()
                    }
                }else{
                    allRecipe.sortByDescending  {
                        it.time.toLong()
                    }
                }

            }
            SortType.Initial ->{
            }
            else ->{
                Log.e("MainViewModel","在调用getAllRewardByTimeOrPrice的时候只允许使用ByTime,ByPrice, Initial")
            }
        }
        return allRecipe
    }
    fun getRewardApplyByUser(account: String):List<Reward>{
        val thisRewards= mutableListOf<Reward>()
        val allReward=initialReward()
        for(reward in allReward){
            val thisRewardJson=reward.rewardApplyAccountList
            if(thisRewardJson!=""){
                val gson=Gson()
                val listType = object : TypeToken<List<ApplyUser>>() {}.type
                val thisRewardApplyAccountList: List<ApplyUser> = gson.fromJson(reward.rewardApplyAccountList, listType)
                thisRewardApplyAccountList.forEach{
                    if(it.account==account){
                        thisRewards.add(reward)

                    }
                }

            }
        }
        return thisRewards.toList()
    }
    private fun initialReward():MutableList<Reward>{
        var thisReward:MutableList<Reward> = mutableListOf()
        val divisionString=DivisionString()
        thisUserList.value?.forEach{ it1->

            divisionString.parseAwardString(it1.reward)?.forEach{
                thisReward.add(it)
            }
        }
        return thisReward
    }
}